<!-- JsonEditor.vue -->
<template>
  <div ref="editorContainer" :style="{ height: height + 'px', width: '100%' }"></div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch, nextTick } from 'vue';
import * as monaco from 'monaco-editor';

const props = defineProps<{
  modelValue: Record<string, any> | null;
  height?: number;
  // 👇 新增：是否已挂载到可见 DOM
  visible?: boolean;
}>();

const emit = defineEmits<{
  (e: 'update:modelValue', value: Record<string, any> | null): void;
  (e: 'error', error: string | null): void;
}>();

const editorContainer = ref<HTMLDivElement | null>(null);
let editor: monaco.editor.IStandaloneCodeEditor | null = null;

const initEditor = () => {
  if (editor || !editorContainer.value) return;

  const initialValue = props.modelValue ? JSON.stringify(props.modelValue, null, 2) : '{}';

  editor = monaco.editor.create(editorContainer.value, {
    value: initialValue,
    language: 'json',
    theme: 'vs',
    automaticLayout: true,
    minimap: { enabled: false },
    scrollBeyondLastLine: false,
    tabSize: 2,
    fontSize: 14,
    readOnly: false
  });

  editor.onDidChangeModelContent(() => {
    const val = editor?.getValue() || '';
    try {
      const parsed = val.trim() ? JSON.parse(val) : null;
      emit('update:modelValue', parsed);
      emit('error', null);
    } catch (err: any) {
      emit('error', err.message);
    }
  });
};

// 👇 当 visible 变为 true 时初始化
watch(
  () => props.visible,
  (newVal) => {
    if (newVal) {
      nextTick(() => {
        initEditor();
      });
    }
  }
);

// 👇 组件挂载时，如果 visible=true，立即初始化
onMounted(() => {
  if (props.visible !== false) {
    nextTick(() => initEditor());
  }
});

// 👇 响应 modelValue 变化（用于外部重置）
watch(
  () => props.modelValue,
  (newVal) => {
    if (editor) {
      const newValStr = newVal ? JSON.stringify(newVal, null, 2) : '{}';
      if (editor.getValue() !== newValStr) {
        editor.setValue(newValStr);
      }
    }
  },
  { deep: true }
);

onUnmounted(() => {
  if (editor) {
    editor.dispose();
    editor = null;
  }
});
</script>
